﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Data;
using System.Text;
using System.Xml;
using System.Threading;
using System.Xml.Linq;
using System.IO.IsolatedStorage;


public class CalculRN
{
    XElement rss;
    public double[,] base_entree;
    public int[] nombreNeuroneParCouche = new int[3];
    public double alpha;

    public string pathSerialise;

    public double[] entree;
    public string status;

    public Reseau res = new Reseau();

    public void calcul_Retropropagation()
    {
        int size = nombreNeuroneParCouche.Length;
        double[] tab_resultat = new double[nombreNeuroneParCouche[size - 1] + 1];

        //Instantiation du RN
        res = new Reseau(nombreNeuroneParCouche, alpha);

        double[] cible = new double[nombreNeuroneParCouche[size - 1]];
        Random r = new Random();
        int NbreAlea = 0;
        double[] entree = new double[nombreNeuroneParCouche[0]];

        int iter = 200000;

        do
        {
            NbreAlea = r.Next(nombreNeuroneParCouche[0]);

            for (int i = 0; i <= entree.Length - 1; i++)
            {
                entree[i] = base_entree[NbreAlea, i];
            }

            for (int i = 0; i <= cible.Length - 1; i++)
            {
                cible[i] = 0;
            }
            cible[NbreAlea] = 1;
            res.insertData(entree);
            for (int i = 1; i <= size - 1; i++)
            {
                res.loadNextLayer(i);
                res.getC(i).calculPotentielCouche();
            }

            //Retropropagation du Gradient
            for (int i = 1; i <= size - 1; i++)
            {
                if (i == 1)
                {
                    for (int j = 0; j <= ((nombreNeuroneParCouche[size - i]) - 1); j++)
                    {
                        Perceptron p = res.getC(size - 1).getPerceptron(j);
                        res.calculErreur(j, cible[j]);
                        p.calculDeltaPoid();
                    }
                }
                else
                {
                    for (int j = 0; j <= ((nombreNeuroneParCouche[size - i]) - 1); j++)
                    {
                        Perceptron p = res.getC(size - i).getPerceptron(j);
                        res.calculErreur(j, size - i);
                        p.calculDeltaPoid();
                    }

                }

            }

            iter = iter - 1;

        } while (iter > 0);

    }

    public static void serialize(Reseau Obj, string pathSerialise)
    {
        XmlSerializer str = new XmlSerializer(typeof(Reseau));

        MemoryStream stream = new MemoryStream();

        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

        //ns.Add("", "");

        //str.Serialize(stream, res, ns);
        //stream.Position = 0;

        //byte[] buffer = new byte[stream.Length + 1];
        //stream.Read(buffer, 0, stream.Length);

        //UTF8Encoding utf8 = new UTF8Encoding();
        //string dd = utf8.GetString(buffer, 0, buffer.Length);

    }

    public void calcul_Activite()
    {
        XElement rss = XElement.Load("XMLSauvegardeReseau_lettre.xml");

        XmlSerializer str = new XmlSerializer(typeof(Reseau));
        res = (Reseau)str.Deserialize(rss.CreateReader());

        int size = nombreNeuroneParCouche.Length;
        double[] tab_resultat = new double[nombreNeuroneParCouche[size - 1]];

        //Présentation du motif a tester
        res.insertData(entree);
        for (int i = 1; i <= size - 1; i++)
        {
            res.loadNextLayer(i);
            res.getC(i).calculPotentielCouche();
        }

        //Construction du tableau de resultat
        for (int i = 0; i <= nombreNeuroneParCouche[size - 1] - 1; i++)
        {
            tab_resultat[i] = res.getC(size - 1).getPerceptron(i).getSortie;
        }

    }


    //public static string calcul_Retropropagation(double[,] base_entree, int[] nombreNeuroneParCouche, double alpha, int nbr_apprentissage, string pathSerialise)
    //{

    //    int size = nombreNeuroneParCouche.Length;
    //    double[] tab_resultat = new double[nombreNeuroneParCouche[size - 1] + 1];

    //    //Instantiation du RN
    //    Reseau res = new Reseau(nombreNeuroneParCouche, alpha);

    //    double[] cible = new double[nombreNeuroneParCouche[size - 1]];
    //    Random r = new Random();
    //    int NbreAlea = 0;
    //    double[] entree = new double[nombreNeuroneParCouche[0]];

    //    int iter = 1000000;

    //    do
    //    {
    //        NbreAlea = r.Next(nbr_apprentissage - 1);

    //        for (int i = 0; i <= entree.Length - 2; i++)
    //        {
    //            entree[i] = base_entree[NbreAlea, i];
    //        }

    //        for (int i = 0; i <= cible.Length - 1; i++)
    //        {
    //            cible[i] = 0;
    //        }

    //        if (base_entree[NbreAlea, nombreNeuroneParCouche[0]] <= 50)
    //        {
    //            cible[0] = 1;
    //        }
    //        else if (base_entree[NbreAlea, nombreNeuroneParCouche[0]] >= 100)
    //        {
    //            cible[nombreNeuroneParCouche[size - 1] - 1] = 1;
    //        }
    //        else
    //        {
    //            cible[base_entree[NbreAlea, nombreNeuroneParCouche[0]] - 50] = 1;
    //        }

    //        res.insertData(entree);
    //        for (int i = 1; i <= size - 1; i++)
    //        {
    //            res.loadNextLayer(i);
    //            res.getC(i).calculPotentielCouche();
    //        }

    //        //Retropropagation du Gradient
    //        for (int i = 1; i <= size - 1; i++)
    //        {
    //            if (i == 1)
    //            {
    //                for (int j = 0; j <= ((nombreNeuroneParCouche[size - i]) - 1); j++)
    //                {
    //                    Perceptron p = res.getC(size - 1).getPerceptron(j);
    //                    res.calculErreur(j, cible[j]);
    //                    p.calculDeltaPoid();
    //                }
    //            }
    //            else
    //            {
    //                for (int j = 0; j <= ((nombreNeuroneParCouche[size - i]) - 1); j++)
    //                {
    //                    Perceptron p = res.getC(size - i).getPerceptron(j);
    //                    res.calculErreur(j, size - i);
    //                    p.calculDeltaPoid();
    //                }

    //            }

    //        }

    //        iter = iter - 1;

    //    } while (iter > 0);

    //    //Sérialisation binaire à la fin de l'apprentissage
    //    string binaryserialisation = serialize(res, pathSerialise);

    //    return "Sérialisation binaire réussie";

    //}

}